package main


type TextWriter struct {
	newLine     string
	output      string
	indent      int
	lineStart   bool
	lineCount   int
	linePos     int
}

var indentStrings = []string{"", "    "}

func getIndentString(level int) string {
	if level >= len(indentStrings) {
		indentStrings = append(indentStrings, getIndentString(level-1) + indentStrings[1])
	}
	return indentStrings[level]
}

func getIndentSize() int {
	return len(indentStrings[1])
}

func (w *TextWriter) Write(s string) {
	if len(s) > 0 {
		if w.lineStart {
			w.output += getIndentString(w.indent)
			w.lineStart = false
		}
		w.output += s
	}
}

func (w *TextWriter) WriteLine() {
	w.output += w.newLine
	w.lineCount++
	w.linePos = len(w.output)
	w.lineStart = true
}

func (w *TextWriter) IncreaseIndent() {
	w.indent++
}

func (w *TextWriter) DecreaseIndent() {
	w.indent--
}

func (w *TextWriter) GetText() string {
	return w.output
}

func (w *TextWriter) RawWrite(s string) {
	if len(s) > 0 {
		if w.lineStart {
			w.lineStart = false
		}
		w.output += s
	}
}

func (w *TextWriter) GetTextPos() int {
	return len(w.output)
}

func (w *TextWriter) GetLine() int {
	return w.lineCount + 1
}

func (w *TextWriter) GetColumn() int {
	if w.lineStart {
		return w.indent*getIndentSize()+1
	} else {
		return len(w.output)-w.linePos+1
	}
}

func (w *TextWriter) GetIndent() int {
	return w.indent
}

func createTextWriter() *TextWriter {
	return &TextWriter{
		newLine:    "\n",
		output:      "",
		indent:      0,
		lineStart:   true,
		lineCount:   0,
		linePos:     0,
	}
}
